/**
 * 
 */
package mtons.utils;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IM4JavaException;
import org.im4java.core.IMOperation;
import org.im4java.process.StandardStream;

/**
 * 图片处理工具类
 * 
 * @author langhsu
 *
 */
public class GMagickUtils {
	private static Logger log = Logger.getLogger(GMagickUtils.class);
	
	public static String gmPath = "D:\\work\\programs\\GraphicsMagick-1.3.20-Q8";
	
	private static IMOperation getIMO(int width, int height) {
		IMOperation op = new IMOperation();
		op.addImage();
		op.resize(width, height);
		op.quality(85d);
		op.addImage();
		
		return op;
	}
	
	public static void scale(String ori, String dest, int width, int height) throws IOException, InterruptedException, IM4JavaException {
		File destFile = new File(dest);
		if (destFile.exists()) {
			destFile.delete();
        }
		
		IMOperation  imo = getIMO(width, height);
		ConvertCmd cmd = new ConvertCmd(true);  
        String osName = System.getProperty("os.name").toLowerCase();      
        if (osName.indexOf("win") >= 0 ) {
            cmd.setSearchPath(gmPath);
        }
        cmd.setErrorConsumer(StandardStream.STDERR);
        
        log.info("imo > " + imo);
        log.info("ori > " + ori);
        log.info("dest > " + dest);
        cmd.run(imo, ori , dest);
	}
	
	public static void validate(File ori, String dest) throws IOException {
		File destFile = new File(dest);
		
		if (ori == null) {
            throw new NullPointerException("Source must not be null");
        }
        if (dest == null) {
            throw new NullPointerException("Destination must not be null");
        }
        if (ori.exists() == false) {
            throw new FileNotFoundException("Source '" + ori + "' does not exist");
        }
        if (ori.isDirectory()) {
            throw new IOException("Source '" + ori + "' exists but is a directory");
        }
        if (ori.getCanonicalPath().equals(destFile.getCanonicalPath())) {
            throw new IOException("Source '" + ori + "' and destination '" + dest + "' are the same");
        }
		if (destFile.getParentFile() != null && destFile.getParentFile().exists() == false) {
            if (destFile.getParentFile().mkdirs() == false) {
                throw new IOException("Destination '" + dest + "' directory cannot be created");
            }
        }
        if (destFile.exists() && destFile.canWrite() == false) {
            throw new IOException("Destination '" + dest + "' exists but is read-only");
        }
	}

	/**
	 * 图片压缩
	 * 
	 * @param ori
	 *            原图位置
	 * @param dest
	 *            目标位置
	 * @param maxSize
	 *            指定压缩后最大边长
	 * @throws java.io.IOException
	 * @throws IM4JavaException 
	 * @throws InterruptedException 
	 */
	public static boolean scaleImage(String ori, String dest, int maxSize) throws IOException, InterruptedException, IM4JavaException {
		File oriFile = new File(ori);
		validate(oriFile, dest);

		BufferedImage src = ImageIO.read(oriFile); // 读入文件
		int w = src.getWidth();
		int h = src.getHeight();

		log.debug("origin with/height " + w + "/" + h);

		int size = (int) Math.max(w, h);
		int tow = w;
		int toh = h;

		if (size > maxSize) {
			if (w > maxSize) {
				tow = maxSize;
				toh = h * maxSize / w;
			} else {
				tow = w * maxSize / h;
				toh = maxSize;
			}
		}

		log.debug("scaled with/height : " + tow + "/" + toh);

		scale(ori, dest, tow, toh);
		
		return true;
	}
	
	public static boolean scaleImageByWidth(String ori, String dest, int maxWidth) throws IOException, InterruptedException, IM4JavaException {
		File oriFile = new File(ori);
		validate(oriFile, dest);

		BufferedImage src = ImageIO.read(oriFile); // 读入文件
		int w = src.getWidth();
		int h = src.getHeight();

		log.debug("origin with/height " + w + "/" + h);

		int tow = w;
		int toh = h;

		if (w > maxWidth) {
			tow = maxWidth;
			toh = h * maxWidth / w;
		}

		log.debug("scaled with/height : " + tow + "/" + toh);

		scale(ori, dest, tow, toh);
		
		return true;
	}

	/**
	 * 自定义宽高缩放图片
	 * 
	 * @throws java.io.IOException
	 * @throws IM4JavaException 
	 * @throws InterruptedException 
	 */
	public static boolean scaleImage(String ori, String dest, int width, int height) throws IOException, InterruptedException, IM4JavaException {
		File oriFile = new File(ori);
		
		validate(oriFile, dest);
		
		BufferedImage src = ImageIO.read(oriFile); // 读入文件
		int w = src.getWidth();
		int h = src.getHeight();

		int tow, toh;

		if (width < w && height < h) {
			tow = width;
			toh = height;
		} else {
			tow = w;
			toh = h;
		}

		scale(ori, dest, tow, toh);
		return true;
	}
}
